// 拦截数组
let ARRAY_METHOD = [
  "push",
  "pop",
  "shift",
  "unshift",
  "reverse",
  "sort",
  "splice"
];

// 思路, 原型式继承: 修改原型链的结构
let arr = [];
// 继承关系: arr -> Array.prototype -> Object.prototype -> ...
// 继承关系: arr -> 改写的方法 -> Array.prototype -> Object.prototype -> ...

let array_methods = Object.create(Array.prototype);
// 上面这个操作相当创建了一个指向Array.prototype的实例
console.log(array_methods.__proto__ === Array.prototype);
console.log(typeof array_methods);

// 遍历方法
ARRAY_METHOD.forEach((method) => {
  // 给刚刚创建的空对象提供这些方法属性
  array_methods[method] = function () {
    console.log("现在调用的是劫持的数组方法");

    // 将数据进行响应式化
    for (let i = 0; i < arguments.length; i++) {
      reactify(arguments[i]);
    }

    // 调用原来的方法
    let res = Array.prototype[method].apply(this, arguments);
    return res;
  };
});

// arr.__proto__ = array_methods;

// 闭包响应式函数
function defineReactive(target, key, value, enumerable) {
  // 确定进来的value一定是引用数据类型，非数组
  if (typeof value === "object" && value != null && !Array.isArray(value)) {
    reactify(value);
  }

  Object.defineProperty(target, key, {
    enumerable: !!enumerable,
    get() {
      console.log("你正在读取" + key + "属性");
      return value;
    },
    set(newValue) {
      console.log("你正在修改" + key + "修改的值为");
      value = newValue;
    }
  });
}

// 让对象响应式化
function reactify(obj) {
  let keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    let key = keys[i];
    let value = obj[key];

    // 判断这个属性是不是引用类型，判断是不是数组
    if (Array.isArray(value)) {
      // 数组
      value.__proto__ = array_methods; // 数组就响应式了

      for (let j = 0; j < value.length; j++) {
        // console.log(value[j]);
        reactify(value[j]); // 递归
      }
    } else {
      defineReactive(obj, key, value, true);
    }
  }
  // console.log(keys);
}
